﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.SharePoint;

namespace Inline.SharePoint.SecurityOnViews.HttpModule
{

    public class SecurityOnViews : IHttpModule
    {

        public String ModuleName
        {
            get { return "Inline.SharePoint.SecurityOnViews.HttpModule"; }
        }

        // In the Init function, register for HttpApplication 
        // events by adding your handlers.
        public void Init(HttpApplication application)
        {

            application.PreRequestHandlerExecute += new EventHandler((this.ProcessRequest)); 

        }

        // Your BeginRequest event handler.
        private void ProcessRequest(Object source, EventArgs e)
        {
            
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;

            if (context.Request.Url != null)
            {

                if (SPContext.Current != null)
                {

                    SPUser currentUser = SPContext.Current.Web.CurrentUser;

                    try
                    {

                        string url = context.Request.Url.ToString(); // Request URL

                        SPSecurity.RunWithElevatedPrivileges(delegate()
                        {

                            using (SPSite site = new SPSite(url))
                            {

                                SPWeb rootweb = site.RootWeb;
                                SPWeb currentWeb = site.OpenWeb();

                                SPList list = rootweb.Lists.TryGetList("Inline.SharePoint.SecurityOnViews");
                                if (list != null)
                                {

                                    string siteRelativeListUrl = url.ToLower().Replace(site.Url.ToLower(), string.Empty);
                                    if(siteRelativeListUrl.IndexOf("?") > -1)
                                        siteRelativeListUrl = siteRelativeListUrl.Remove(siteRelativeListUrl.IndexOf("?")); // Strip URL properties

                                    try
                                    {

                                        SPList listFromUrl = currentWeb.GetList(siteRelativeListUrl);
                                        SPView viewFromSiteRelativeUrl = GetViewViaSiteRelativeUrl(listFromUrl, siteRelativeListUrl);

                                        if (viewFromSiteRelativeUrl != null)
                                        {

                                            SPQuery query = new SPQuery();
                                            query.Query = @"<Where><Eq><FieldRef Name=""Title"" /><Value Type=""Computed"">" +
                                                viewFromSiteRelativeUrl.ID.ToString().ToUpper() + 
                                                "</Value></Eq></Where>";

                                            SPListItemCollection iColl = list.GetItems(query);

                                            for (int i = 0; i < iColl.Count; i++)
                                            {

                                                if (!iColl[i].DoesUserHavePermissions(currentUser, SPBasePermissions.ViewListItems))
                                                {

                                                    if (context.Request.UrlReferrer == null)
                                                        context.Response.Redirect(currentWeb.Url + "/_layouts/AccessDenied.aspx");
                                                    else
                                                        context.Response.Redirect(currentWeb.Url + "/_layouts/AccessDenied.aspx?Source=" + context.Request.UrlReferrer.ToString());

                                                    break;

                                                }

                                            }

                                        }

                                    }
                                    catch
                                    { }

                                    //string viewName = string.Empty;
                                    //viewName = url.Replace(site.Url.ToLower(), string.Empty); // Site relative view url

                                    //if(!string.IsNullOrEmpty(viewName))
                                    //{

                                    //    SPListItemCollection iColl = list.Items;

                                    //    for (int i = 0; i < iColl.Count; i++)
                                    //    {

                                    //        if (iColl[i][SPBuiltInFieldId.Title] != null)
                                    //        {

                                    //            if (viewName.ToLower().Contains(iColl[i][SPBuiltInFieldId.Title].ToString().ToLower()))
                                    //            {

                                    //                web.EnsureUser(currentUser.LoginName);
                                    //                if (!iColl[i].DoesUserHavePermissions(currentUser, SPBasePermissions.Open))
                                    //                {

                                    //                    if (context.Request.UrlReferrer == null)
                                    //                        context.Response.Redirect(web.Url + "/_layouts/AccessDenied.aspx");
                                    //                    else
                                    //                        context.Response.Redirect(web.Url + "/_layouts/AccessDenied.aspx?Source=" + context.Request.UrlReferrer.ToString());

                                    //                }

                                    //                break; // Don't check the rest

                                    //            }

                                    //        }

                                    //    }

                                    //}

                                }

                            }

                        });

                    }
                    catch { }

                }

            }

        }

        public void Dispose() { }

        public SPView GetViewViaSiteRelativeUrl(SPList list, string viewSiteRelativeUrl)
        {

            SPViewCollection vColl = list.Views;
            for (int i = 0; i < vColl.Count; i++)
            {

                if (vColl[i].ServerRelativeUrl.ToLower() == viewSiteRelativeUrl.ToLower())
                    return vColl[i];

            }

            return null;

        }

    }

}